///@file FEProblem.cpp
///@brief Implementation of the class representing a Finite Element problem
///@author Arnaud Duval
///@version 0.0
///@date 2011/03/03

#include "FEProblem.h"

///@brief Default constructor
FEProblem::FEProblem()
{

}

///@brief Constructor with arguments
///@param theMesh Pointer to the mesh of the problem
FEProblem::FEProblem(Mesh *theMesh)
{
    mesh = theMesh;
}

///@brief destructor
FEProblem::~FEProblem()
{
    mesh = NULL; 
}

///@brief Add a node group to current problem
///@param groupName The name of the group to add
void FEProblem::AddNodeGroup(std::string groupName)
{
    if(!GroupExists(groupName))
    {
        NodeGroup group(groupName);
        nodeGroups.push_back(group);
    }
    else
        std::cerr << "Group " << groupName << " already exists\n";
}

///@brief Return true if group exists
///@param groupName Name of the group to check
bool FEProblem::GroupExists(std::string groupName)
{
    for(std::list<NodeGroup>::iterator lit = nodeGroups.begin() ; lit != nodeGroups.end() ; ++lit)
    {
        if(lit->GetName() == groupName)
            return true;
    }
    return false;
}

///@brief Add a node to a group
///@param nodeName Name of the node to add
///@param groupName Name of the group in which the node should be added
bool FEProblem::AddNodeToGroup(std::string nodeName, std::string groupName)
{
    Node* pointer = mesh->GetPointerToNode(nodeName);
    if(!pointer)
        return false;
    for(std::list<NodeGroup>::iterator lit = nodeGroups.begin() ; lit != nodeGroups.end() ; ++lit)
    {
        if(lit->GetName() == groupName)
        {
            lit->AddNode(pointer);
            return true;
        }
    }
    return false;
}

///@brief Overload of << operator
///@param s Out stream
///@param f FEProblem object to put in the out stream
std::ostream& operator << (std::ostream& s, const FEProblem& f)
{
    s << *(f.mesh) << "\n";
    for(std::list<NodeGroup>::const_iterator it = f.nodeGroups.begin() ; it != f.nodeGroups.end() ; ++it)
        s << *it << "\n";
    return s;
}